<template>
    <view class="ul-top-navbar" :class="{ ios: isIos }">
        <!-- 导航占位整个高度 -->
        <view v-if="usePlaceholder" :style="'height: ' + navbarHeight + 'px'" />
        <view class="ul-navbar-plus-warpper">
            <!-- 导航栏背景 -->
            <view class="bg" :style="bgStyle" />
            <!-- 顶部状态栏占位，信号，电量等 -->
            <view class="status-bar" :style="'height: ' + systemInfo.statusBarHeight + 'px'" />
            <!-- 导航内容区域 -->
            <view class="content" :class="[textStyle]" :style="contentStyle">
                <!-- 左侧返回按钮区域 -->
                <view
                    v-if="!hideBackButton"
                    class="left"
                    :class="{ back: !showHomeButton, home: showHomeButton }"
                    :style="leftStyle"
                    @click="onBackPage"
                >
                    <view class="iconfont" />
                </view>
                <!-- 标题区域 -->
                <view v-if="title && showPageTitle" class="title" :style="titleStyle">{{ title }}</view>
            </view>
        </view>
    </view>
</template>

<script>
import { buildCss } from '@/app/common/js/uni-api-plus/utils/build-css.js';

/**
 * 顶部导航通用组件
 * @param {String} textStyle                导航栏标题颜色及状态栏前景颜色，仅支持 black/white
 * @param {String} title                    导航栏标题
 * @param {String|Array} titleColor         导航栏标题颜色，如果为数组时第一个颜色为初始颜色，第二个颜色滚动后颜色
 * @param {Boolean} transparent             是否启用透明导航栏
 * @param {String} backgroundColor          导航栏背景色
 * @param {Boolean} hideBackButton          隐藏返回按钮|首页按钮
 * @param {String|Number} gradientDistance  页面滚动时距离窗口顶部多少时开始改变背景色
 * @param {Boolean} usePlaceholder          是否使用导航栏占位高度
 * @param {Boolean} alwaysShowPageTitle     是否始终显示页面标题，无论是否开启导航透明
 */
export default {
    props: {
        textStyle: {
            type: String,
            default: 'black'
        },
        title: {
            type: String,
            default: ''
        },
        titleColor: {
            type: [String, Array],
            default: ''
        },
        transparent: {
            type: Boolean,
            default: false
        },
        backgroundColor: {
            type: String,
            default: '#f8f8f8'
        },
        hideBackButton: {
            type: Boolean,
            default: false
        },
        gradientDistance: {
            type: [String, Number],
            default: 0
        },
        usePlaceholder: {
            type: Boolean,
            default: false
        },
        alwaysShowPageTitle: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            scrollTop: 0,
            showBackcolor: false,
            debug: true
        };
    },
    created() {
        if (typeof this.$onPage === 'function' && this.transparent) {
            this.$onPage('onPageScroll', e => {
                this.debounce(() => {
                    this.scrollTop = e.scrollTop;
                });
            });
        }
    },
    computed: {
        /**
         * 获取系统信息
         */
        systemInfo() {
            return uni.getSystemInfoSync();
        },

        /**
         * 是否显示回到首页按钮
         */
        showHomeButton() {
            return getCurrentPages().length === 1;
        },

        /**
         * 判断是否为IOS系统
         */
        isIos() {
            return this.systemInfo.system.toUpperCase().includes('IOS');
        },

        /**
         * 是否显示页面标题
         */
        showPageTitle() {
            return this.alwaysShowPageTitle ? true : this.showBackcolor;
        },

        /**
         * 计算右上角胶囊按钮布局信息
         */
        buttonRect() {
            const rect = uni.getMenuButtonBoundingClientRect();
            const systemInfo = this.systemInfo;
            rect.marginTop = rect.top - systemInfo.statusBarHeight;
            rect.marginRight = systemInfo.windowWidth - rect.right;
            return rect;
        },

        /**
         * 整个导航高度: 状态栏高度 + 菜单按钮上边距(4px) + 菜单按钮高度 + 菜单按钮下边距(4px)
         */
        navbarHeight() {
            const buttonRect = this.buttonRect;
            return this.systemInfo.statusBarHeight + buttonRect.marginTop * 2 + buttonRect.height;
        },

        /**
         * 背景样式
         */
        bgStyle() {
            const css = {
                height: `${this.navbarHeight}px`,
                background: this.backgroundColor
            };

            if (this.transparent) {
                const distance = parseInt(this.gradientDistance || this.navbarHeight);

                if (this.scrollTop > distance) {
                    this.showBackcolor = true;
                    Object.assign(css, {
                        opacity: 1
                    });
                } else {
                    this.showBackcolor = false;
                    const opacity = (this.scrollTop / distance).toFixed(2);
                    Object.assign(css, {
                        opacity: opacity
                    });
                }
            }

            return buildCss(css);
        },

        /**
         * 内容样式
         */
        contentStyle() {
            return buildCss({
                width: `calc(750rpx - ${this.buttonRect.marginRight * 2}px)`,
                height: `${this.buttonRect.height}px`,
                margin: `${this.buttonRect.marginTop}px auto`,
                color: `${this.textStyle}`
            });
        },

        /**
         * 左侧按钮样式
         */
        leftStyle() {
            const height = this.buttonRect.height;
            return buildCss({
                width: `${this.showHomeButton ? height : height / 1.5}px`,
                height: `${this.buttonRect.height}px`
            });
        },

        /**
         * 标题样式
         */
        titleStyle() {
            const buttonRect = this.buttonRect;
            const systemInfo = this.systemInfo;
            const width = systemInfo.windowWidth - buttonRect.width * 2 - buttonRect.marginRight * 4;

            const css = {
                width: `${width}px`,
                lineHeight: `${buttonRect.height}px`,
                fontSize: `${systemInfo.fontSizeSetting}px`
            };

            if (this.titleColor) {
                if (Array.isArray(this.titleColor)) {
                    css.color = this.showBackcolor ? this.titleColor[1] : this.titleColor[0];
                } else {
                    css.color = this.titleColor;
                }
            }

            return buildCss(css);
        }
    },
    methods: {
        /**
         * 生成css样式
         * @param {Object} obj
         */
        buildCss(obj) {
            let css = [];
            for (let name in obj) {
                css.push(`${name}: ${obj[name]}`);
            }
            return css.join(';');
        },

        /**
         * 触发页面滚动事件
         * @param {Object} e
         */
        emitPageScroll(e) {
            if (this.transparent) {
                this.debounce(() => {
                    this.scrollTop = e.scrollTop;
                });
            }
        },

        /**
         * 防止重复执行
         * @param {Object} callback
         */
        debounce(callback) {
            clearTimeout(this.timer);
            this.timer = setTimeout(callback, 10);
        },

        /**
         * 返回上一页/返回首页
         */
        onBackPage() {
            uni.navigateBack();
        }
    }
};
</script>

<style lang="scss" scoped>
.ul-navbar-plus-warpper {
    position: fixed;
    top: 0;
    left: 0;
    width: 750rpx;
    height: auto;
    z-index: 9999;

    .bg {
        position: absolute;
        z-index: -1;
        height: 100%;
        width: 100%;
        opacity: 1;
    }
}

.ios {
    .left {
        position: absolute;
    }

    .title {
        margin: 0 auto !important;
        text-align: center;
    }
}

.content {
    position: relative;
    display: flex;
    width: 750rpx;
    height: auto;

    .left {
        display: flex;
        text-align: center;
        align-items: center;
        justify-content: center;
        height: 100%;

        .icon {
            width: 36rpx;
            height: 36rpx;
        }
    }

    .left.home {
        border-radius: 50%;
        background: #ffffff;

        .iconfont::before {
            content: '\ec0a';
        }
    }

    .left.back {
        .iconfont::before {
            content: '\e63a';
        }
    }

    .title {
        margin-left: 14rpx;
        overflow: hidden;
    }
}

@font-face {
    font-family: 'iconfont';
    src: url('data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAALwAA0AAAAABwAAAAKaAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACCShEICoFcgUELDAABNgIkAxIEIAWFAgc4G/IFEZWbQ8l+JpjnMfUN4OQgxuAoaZgVOdXVO2GTN/HwtVa+391Ls2FSrKIP1Na6IPiTKQ+A8uKAbDSSBZbsSI9fv7Z34qX8hFk8onatp39PFFiYoRFaYOrUj+1lwfcAJkRLd/ljHWNh6r1awVrQUjD35w2AiZtxi3BybpsCSjvv8ixLxwQKLI7moGxrlP69PT6gPxD9eruH28uzyIYxQRE+bBTBLAS8ubKIhC+r9jOydmAMpiEJWREKEkoR5zRIx9NrwFl4f/zGJtokjUxut5r8ENz/5nd03lfvs137jB8BgAUCGRlzBOghC8xRLEZTEVIVua4B/++Z+UL5IwCiSQAiIQEAAj4/6poKGqBCwTBWACgACHna5DJxZGcku9EDqWG0Qc1Qj7dHgxjdSXB7Qg0b9Ga6aXzunrxXh250N6lV7L9FVyduAFWuRiR3uXeZzfGSDuIeXFHhyRf+Nhd3LyYlA8uPHqgPfbs/enK99Q7sP4Op0/PGm/pP/+HbP7YTY+nOivbYD7OUvh+AQDD33+JPMH7wv90tBrbfQH07P9FWgLYEgiGLU0B+YjWgFO5XolBvBRoWyyChUqEGYJKvFMBkiwUIbSsRIGkZQYCsbX+Aou1SgIauOwGa2j5RQGVZDArQNTnOyaJ0sBBGwwSDaDLOJjSbYAdQkBNowzRX0aYJXqAV4/5P8zCIHLunjFjIqRB/qUXSteRiXM9pFaNV1gAJgr8UZ5m96+iJD2l64/Ub6l0+X4VWWFtYwWkVfr1Y5QKn6FY+e1zy+mQbzCTQs2uEY4kkWded0IdfKWXCC7jMq1+fbMNMxxj9gkpvRfy33s8BOXPvW1qiytJC0lLEtixSNr1sBB0zA5e6GAAUqIqqaCZFbf4u9DkAAAA=')
        format('truetype');
}

.iconfont {
    font-family: 'iconfont' !important;
    font-size: 40rpx;
    font-style: normal;
}

.icon-fanhui:before {
    content: '\e63a';
}

.icon-home:before {
    content: '\ec0a';
}
</style>
